#import "BWStitchSelection.h"
#import "BWStitchArray.h"

@implementation BWStitchSelection

- (id) init
{
    if ([super init] == nil) {
        return (nil);
    }

    selectedStitches = [[NSMutableSet alloc] init];

    return (self);

} // init


- (void) dealloc
{
    [selectedStitches release];
    [stitches release];

    [super dealloc];

} // dealloc


- (void) setStitches: (BWStitchArray *) s
{
    if (s != stitches) {
        // this is surely an abuse of KVO
        [stitches removeObserver: self  forKeyPath: @"stitches"];

        [s retain];
        [stitches release];

        stitches = s;

        [stitches addObserver: self
                  forKeyPath: @"stitches"
                  options: NSKeyValueObservingOptionOld
                  context: NULL];
    }

} // setStitches


- (void) selectAll
{
    [self willChangeValueForKey: @"count"];
    [selectedStitches addObjectsFromArray: [stitches stitches]];
    [self didChangeValueForKey: @"count"];

} // selectAll


- (void) unselectAll
{
    [self willChangeValueForKey: @"count"];
    [selectedStitches removeAllObjects];
    [self didChangeValueForKey: @"count"];

} // unselectAll


- (void) selectStitch: (BWStitch *) stitch
    unselectingOthers: (BOOL) unselectOthers
{
    if (unselectOthers) {
        [self unselectAll];
    }

    [self willChangeValueForKey: @"count"];
    [selectedStitches addObject: stitch];
    [self didChangeValueForKey: @"count"];

} // selectStitch


- (void) unselectStitch: (BWStitch *) stitch
{
    [self willChangeValueForKey: @"count"];
    [selectedStitches removeObject: stitch];
    [self didChangeValueForKey: @"count"];

} // unselectStitch


- (int) count
{
    return ([selectedStitches count]);
} // count


- (BWStitch *) arbitraryStitch
{
    BWStitch *stitch = nil;

    if ([selectedStitches count] != 0) {
        stitch = [selectedStitches anyObject];
    }

    return (stitch);

} // arbitraryStitch


- (BWStitch *) selectedStitch
{
    return ([self arbitraryStitch]);

} // selectedStitch



- (NSEnumerator *) objectEnumerator
{
    return ([selectedStitches objectEnumerator]);

} // objectEnumerator


- (BOOL) isStitchSelected: (BWStitch *) stitch
{
    if ([selectedStitches member: stitch] != nil) {
        return (YES);
    } else {
        return (NO);
    }

} // isStitchSelected


- (void) observeValueForKeyPath: (NSString *) keyPath
                       ofObject: (id) object
                         change: (NSDictionary *) change
                        context: (void *) context
{
    NSNumber *kindNumber;

    kindNumber = [change valueForKey: NSKeyValueChangeKindKey];

    if ([kindNumber intValue] == NSKeyValueIntersectSetMutation) {
        NSArray *old = [change valueForKey: NSKeyValueChangeOldKey];
        
        [self willChangeValueForKey: @"count"];
        int i;
        for (i = 0; i < [old count]; i++) {
            BWStitch *stitch = [old objectAtIndex: i];
            [selectedStitches removeObject: stitch];
        }
        [self didChangeValueForKey: @"count"];
    }

} // observeValueForKeyPath


- (NSIndexSet *) indexesForSelection
{
    NSMutableIndexSet *indexes = [NSMutableIndexSet indexSet];

    NSEnumerator *enumerator = [selectedStitches objectEnumerator];

    // O(N^2) :-(
    BWStitch *stitch;
    while (stitch = [enumerator nextObject]) {
        int index = [stitches indexOfStitch: stitch];
        [indexes addIndex: index];
    }

    return (indexes);

} // indexesForSelection

@end // BWStitchSelection

